﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace Engine
{
    public abstract class Entity : GameComponent
    {
        Entity parent;

        public Entity Parent
        {
            get { return parent; }
        }

        public virtual Vector3 Position
        {
            get { return localWorld.Translation; }
            set { localWorld.Translation = value; }
        }

        public Vector3 Direction
        {
            get { return localWorld.Forward; }
            set
            {
                Rotation = Matrix.CreateLookAt(Vector3.Zero, value, Up);
            }
        }

        public Vector3 Up
        {
            get { return localWorld.Up; }
            set
            {
                Rotation = Matrix.CreateLookAt(Vector3.Zero, Direction, value);
            }
        }

        public Vector3 Right
        {
            get { return localWorld.Right; }
        }


        protected Matrix rotation = Matrix.Identity;
        public Matrix Rotation
        {
            get { return rotation; }
            set
            {
                rotation = value;
                UpdateMatrices();
            }
        }

        protected Matrix scale = Matrix.Identity;
        public Vector3 Scale
        {
            get { return new Vector3(scale.M11, scale.M22, scale.M33);}
            set
            {
                scale.M11 = value.X;
                scale.M22 = value.Y;
                scale.M33 = value.Z;
                UpdateMatrices();
            }
        }

        protected Matrix localWorld = Matrix.Identity;
        public Matrix LocalWorld { get { return localWorld; } set { localWorld = value; } }

        protected Matrix offset = Matrix.Identity;
        public Matrix OffsetWorld { get { return offset; } set { offset = value; } }

        public Matrix ParentWorld
        {
            get
            {
                if (parent != null)
                    return parent.World;
                else
                    return Matrix.Identity;
            }
        }

        /// <summary>
        /// The total world of this entity.
        /// </summary>
        public Matrix World { get { return localWorld * offset * ParentWorld; } }

        public BoundingBox BoundingBox { get; protected set; }
        public BoundingSphere BoundingSphere { get; protected set; }

        //public Controller controller;

        #region Constructors

        public Entity(Entity parent)
            : base(Engine.Instance.Game)
        {
            this.parent = parent;
        }

        //public Entity(

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        private void UpdateMatrices()
        {
            Vector3 pos = new Vector3()
            {
                X = localWorld.M41,
                Y = localWorld.M42,
                Z = localWorld.M43,
            };

            Matrix.Multiply(ref scale, ref rotation, out localWorld);

            localWorld.M41 = pos.X;
            localWorld.M42 = pos.Y;
            localWorld.M43 = pos.Z;
            
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                //Dispose of unmanaged objects here.
            }
            base.Dispose(disposing);
        }
        #endregion


    }
}
